﻿#include "GAF_Window.h"
#include "GAF_Application.h"
#include "GAF_Platform.h"

#define WINDOW_NULL			((Scene*)0x11111111)

namespace GAF
{
	void Window::ResetCWStruct(CreateWindow& cw)
	{
		cw.pWindow		= NULL;
		cw.nWidth		= 800;
		cw.nHeight		= 600;
		cw.isFullScreen		= false;
		cw.isHardware		= false;
		cw.strTitle		= "App";

		cw.bdlOther.Clean();
	}

	Window::Window()
	{
		ATTRIB(FullScreen)	= false;
		m_pWndHandle		= NULL;
		m_pMainScene		= WINDOW_NULL;
		m_pTopScene		= WINDOW_NULL;
		m_pShowScene		= WINDOW_NULL;
		m_pCallScene		= WINDOW_NULL;
		m_isExitWnd		= false;
		m_isShowWnd		= false;

		_MEMCPY(&ATTRIB(Size), &GAF_SIZE_ZERO, sizeof(Size));

#ifdef GAF_FPS_CONTROL
		SetFPS(0);
		m_ttSaveFPST = 0;
		m_ttFPSTUse = 0;
#endif
	}

	Window::~Window()
	{
	}

	bool Window::InitWindow(CreateWindow& cw)
	{
		GAF_ASSERT_R(m_pWndHandle == NULL, false);

		m_pWndHandle = OnInitWindow(cw);

		if(m_pWndHandle == NULL)
			m_pWndHandle = GAF_pTHEPLATFORM->NewWindow(cw);

		if(m_pWndHandle == NULL)
			return false;

		ATTRIB(Size).nWidth = cw.nWidth;
		ATTRIB(Size).nHeight = cw.nHeight;
		ATTRIB(FullScreen) = cw.isFullScreen;

		return true;
	}

	bool Window::ShowWindow()
	{
		m_isShowWnd = GAF_pTHEPLATFORM->ShowWindow(m_pWndHandle);
		return m_isShowWnd;
	}

	void Window::HideWindow()
	{
		GAF_pTHEPLATFORM->HideWindow(m_pWndHandle);
		m_isShowWnd = false;
	}

	bool Window::RunWindow()
	{
		GAF_CHECK_R(m_isShowWnd, false);

		while(!GAF_pTHEAPP->IsQuit())
		{
			if(!OnceWindow())
				break;

			// 翻转窗口
			FlipWindow();

			FPSControl();
		}

		return true;
	}

	void Window::UpdateWindow()
	{
		UpdateScene(m_pTopScene);

		// 应用程序更新
		GAF_pTHEAPP->UpdateApp();
	}

	void Window::RenderWindow()
	{
		if(m_pTopScene != WINDOW_NULL)
		{
			// 更新顶层场景绘制对象
			m_pTopScene->ResetCanvas();
			// 渲染顶层场景
			RenderScene(m_pTopScene);
		}

		GAF_pTHEPLATFORM->RanderWindow(m_pWndHandle);
	}

	void Window::FlipWindow()
	{
		GAF_pTHEPLATFORM->FlipWindow(m_pWndHandle);
	}

 	void Window::IdleWindow()
 	{
		GAF_pTHEAPP->UpdateTimers();
		GAF_pTHEAPP->UpdateExactTimers();
	}

	bool Window::OnceWindow()
	{
		// 切换场景
		if(!SwitchScene())
			return false;

		// 更新窗口
		UpdateWindow();
		// 渲染窗口
		RenderWindow();
		// 空闲窗口
		IdleWindow();

		return true;
	}

	void Window::ShowScene(Scene* pScene)
	{
		m_pShowScene = pScene;
	}

	void Window::CallScene(Scene* pScene)
	{
		m_pCallScene = pScene;
	}

	bool Window::SwitchScene()
	{
		// 检查顶层呼叫场景
		if(m_pTopScene != WINDOW_NULL && m_pTopScene != m_pMainScene)
		{
			// 和下面代码重复，需考虑重构问题
			if(m_pTopScene->IsExit())
			{
				// 呼叫场景退出
				Scene* pEndScene = m_pTopScene;
				m_pTopScene = pEndScene->GetBackScene();

				EndScene(pEndScene);
				m_pTopScene->OnCallReturn(pEndScene);
				pEndScene = NULL;
			}
		}

		// 更换主场景
		if(m_pShowScene != WINDOW_NULL && m_pShowScene != m_pMainScene)
		{
			// 顶层场景退出
			if(m_pTopScene != m_pMainScene)
			{
				Scene* pEndScene = NULL;
				do
				{
					// 呼叫场景退出
					pEndScene = m_pTopScene;
					m_pTopScene = pEndScene->GetBackScene();

					EndScene(pEndScene);
					m_pTopScene->OnCallReturn(pEndScene);
					pEndScene = NULL;
				} while (m_pTopScene->GetBackScene() != NULL);
			}

			// 卸载之前的主场景
			if(m_pMainScene != WINDOW_NULL)
			{
				EndScene(m_pMainScene);
				GAF_pTHEAPP->TurnOffScene(m_pMainScene);
			}

			// 更换主场景
			m_pMainScene = m_pShowScene;
			m_pShowScene = WINDOW_NULL;

			// 主场景不存在时退出
			if(m_pMainScene == NULL)
				return false;

			// 开始场景
			if(!StartScene(m_pMainScene))
			{
				GAF_pTHEAPP->TurnOffScene(m_pMainScene);
				m_pMainScene = WINDOW_NULL;
				return false;
			}

			// 设为顶层场景
			m_pTopScene = m_pMainScene;
		}

		// 呼叫场景
		if(m_pCallScene != WINDOW_NULL)
		{
			if(m_pTopScene != m_pCallScene)
			{
				if(StartScene(m_pCallScene))
				{
					m_pTopScene = m_pCallScene;
				}
			}
			m_pCallScene = WINDOW_NULL;
		}

		return true;
	}

	bool Window::StartScene(Scene* pScene)
	{
		pScene->SetWindow(this);

		Scene* _pTop = (m_pTopScene == WINDOW_NULL) ? NULL : m_pTopScene;

		if(!pScene->Start(_pTop))
		{
			pScene->SetWindow(NULL);
			return false;
		}

		GAF_pTHEPLATFORM->CleanCommandBuffer(m_pWndHandle);
		return true;
	}

	void Window::EndScene(Scene* pScene)
	{
		GAF_pTHEPLATFORM->CleanCommandBuffer(m_pWndHandle);

		pScene->End();
	}

	void Window::UpdateScene(Scene* pScene)
	{
		static Command s_cmdGet;

		// 顺序索取所有事件
		while(!pScene->IsExit() && GetCommand(s_cmdGet))
		{
			if(GAF_COMMAND_ISWINDOW(s_cmdGet.nCmdID))
			{
				switch(s_cmdGet.nCmdID)
				{
				case COMMAND_QUIT:
					GAF_pTHEAPP->QuitApp(true);
					break;
				default:
					break;
				}
			}
			else if(GAF_COMMAND_ISOPERATION(s_cmdGet.nCmdID))
			{
				switch(s_cmdGet.nCmdID)
				{
				case COMMAND_KEY_DOWN:
					pScene->KeyDown(s_cmdGet.lParam1);
					break;
				case COMMAND_KEY_UP:
					pScene->KeyUp(s_cmdGet.lParam1);
					break;
				case COMMAND_CURSOR_DOWN:
					pScene->CursorDown(s_cmdGet.lParam1, s_cmdGet.lParam2);
					break;
				case COMMAND_CURSOR_UP:
					pScene->CursorUp(s_cmdGet.lParam1, s_cmdGet.lParam2);
					break;
				case COMMAND_CURSOR_MOVE:
					pScene->CursorMove(s_cmdGet.lParam2);
					break;
				default:
					break;
				}
			}
		}

		// 更新
		pScene->Update();
	}

	void Window::RenderScene(Scene* pScene)
	{
		if(!pScene->IsFullWindow())
		{
			Scene* pBackScene = pScene->GetBackScene();

			if(pBackScene != NULL)
			{
				RenderScene(pBackScene);
			}
		}

		pScene->GetCanvas()->Render();
	}

	void Window::SetFPS(UINT nFPS)
	{
		m_nFPS = nFPS;

		if(m_nFPS == 0)
			m_ttFPST = 0;
		else
			m_ttFPST = 1000 / nFPS;
	}

	UINT Window::GetFPS()
	{
		return m_nFPS;
	}

	void Window::SetTitle(const _STRING strTitle)
	{
		GAF_pTHEPLATFORM->SetWindowTitle(m_pWndHandle, strTitle);
	}

	Scene* Window::GetTopScene()
	{
		if(m_pTopScene == WINDOW_NULL)
			return NULL;
		return m_pTopScene;
	}

	bool Window::GetCommand(Command& cmdGet)
	{
		cmdGet.Reset();

		if(GAF_pTHEPLATFORM->GetCommand(m_pWndHandle, cmdGet))
		{
			if(GAF_COMMAND_ISWINDOW(cmdGet.nCmdID))
			{
				if(OnGetCommand(cmdGet))
				{
					cmdGet.nCmdID = COMMAND_NOTHING;
					return false;
				}
			}
			else if(GAF_COMMAND_ISOPERATION(cmdGet.nCmdID))
			{
				if(m_pTopScene->OnGetCommand(cmdGet))
				{
					cmdGet.nCmdID = COMMAND_NOTHING;
					return false;
				}
			}

			return true;
		}

		return false;
	}

	WindowHandle Window::GetHandle()
	{
		return m_pWndHandle;
	}

 	void Window::FPSControl()
 	{
//  		m_ttFPSUse = GAF_pTHEPLATFORM->GetTimeTicks() - m_ttSaveFPS;
//  		if(m_ttFPSUse < ATTRIB(FPSTime))
// 		{
// 			GAF_pTHEPLATFORM->Delay(ATTRIB(FPSTime) - m_ttFPSUse);
// 		}

// 		GAF_NOTE("Use Time = %d\n", GAF_pTHEPLATFORM->GetTimeTicks() - m_ttSaveFPS);

#ifdef GAF_FPS_CONTROL
		do
		{
#endif
#ifdef GAF_FPS_CONTROL
			m_ttFPSTUse = GAF_pTHEPLATFORM->GetTimeTicks() - m_ttSaveFPST;
// 			GAF_NOTE("Frame Ues Time = %d\n", m_ttFPSTUse);
		}while(m_ttFPSTUse < m_ttFPST);
		m_ttSaveFPST = GAF_pTHEPLATFORM->GetTimeTicks();
#endif
 	}
}
